#==============================================================#
# File      :   config.yml
# Ctime     :   2021-04-03
# Mtime     :   2022-12-04
# Desc      :   Promtail logging collector agent
# Path      :   /etc/promtail/config.yml
# License   :   AGPLv3 @ https://pigsty.io/docs/about/license
# Copyright :   2018-2025  Ruohang Feng / Vonng (rh@vonng.com)
#==============================================================#

server:
  http_listen_port: {{ promtail_port|default(9080) }}
  grpc_listen_port: 9097

positions:                     # location of position status file
  filename: {{ promtail_positions }}
  sync_period: 10s             # How often to update the positions file
  ignore_invalid_yaml: true    # Whether to ignore & later overwrite positions files that are corrupted

clients:
  - url:   {{ loki_url }}
    external_labels:
      ip:  {{ inventory_hostname }}
      cls: {{ node_cluster|default('nodes') }}
      ins: {{ nodename }}

scrape_configs:

  ################################################################
  #                        Nodes Logs                            #
  ################################################################
  # collect /var/log/messages dmesg cron logs on all nodes
  - job_name: nodes
    static_configs:
      - targets:
          - localhost
        labels:
          src: syslog
          job: node
{% if os_package|default('rpm') == 'deb' %}
          __path__: /var/log/syslog
{% else %}
          __path__: /var/log/messages
{% endif %}

      - targets:
          - localhost
        labels:
          src: dmesg
          job: node
          __path__: /var/log/dmesg

      - targets:
          - localhost
        labels:
          src: cron
          job: node
          __path__: /var/log/cron


{% if inventory_hostname in groups["infra"] %}
  ################################################################
  #                       Infra Log                              #
  ################################################################
  # collect nginx logs on meta nodes

{% if inventory_hostname in groups['infra'] and (nginx_enabled is not defined or nginx_enabled|bool) %}
  - job_name: nginx
    static_configs:
      - targets:
          - localhost
        labels:
          src: nginx
          job: infra
          __path__: /var/log/nginx/*.log

      - targets:
          - localhost
        labels:
          src: nginx-error
          job: infra
          __path__: /var/log/nginx-error.log

    pipeline_stages:
      - match:
          selector: '{src="nginx"}'
          stages:
            - regex:
                # logline example: 127.0.0.1 - - [21/Apr/2020:13:59:45 +0000] "GET /?foo=bar HTTP/1.1" 200 612 "http://example.com/lekkebot.html" "curl/7.58.0"
                expression: '.*\[(?P<timestamp>.*)\].*'
            - timestamp:
                source: timestamp
                format: '02/Jan/2006:15:04:05 -0700'

      - match:
          selector: '{src="nginx-error"}'
          stages:
            - regex:
                # logline example: 127.0.0.1 - - [21/Apr/2020:13:59:45 +0000] "GET /?foo=bar HTTP/1.1" 200 612 "http://example.com/lekkebot.html" "curl/7.58.0"
                expression: '(?P<timestamp>\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}).*'
            - timestamp:
                source: timestamp
                format: '2006/Jan/02 15:04:05'

{% endif %}

{% endif %}


{% if pg_cluster is defined and pg_seq is defined %}
  ################################################################
  #                      PostgreSQL Logs                         #
  ################################################################
  - job_name: postgres
    static_configs:
      - targets:
          - localhost
        labels:
          src: postgres
          job: pgsql
          cls: {{ pg_cluster }}
          ins: {{ pg_cluster }}-{{ pg_seq }}
          __path__: {{ pg_log_dir }}/*

    pipeline_stages:
      - match:
          selector: '{src="postgres"}'
          stages:
            - multiline:
                firstline: '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} \w+(,|\s).*'
                max_wait_time: 8s
                max_lines: 8192
            - regex:
                expression: '^(?P<ts>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} \w+)(,|\s).*$'
            - timestamp:
                source: ts
                format: '2006-01-02 15:04:05 MST'


  #==============================================================#
  #                        Patroni Logs                          #
  #==============================================================#
{% if patroni_enabled is defined and patroni_enabled|bool %}
  - job_name: patroni
    static_configs:
      - targets:
          - localhost
        labels:
          src: patroni
          job: pgsql
          cls: {{ pg_cluster }}
          ins: {{ pg_cluster }}-{{ pg_seq }}
          __path__: {{ patroni_log_dir }}/patroni.log

    pipeline_stages:
      - match:
          selector: '{src="patroni"}'
          stages:
            - regex:
                expression: '^(?P<ts>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [+-]\d{4}) (?P<level>\w+): (?P<message>.*)'
            - labels:
                level:
            - timestamp:
                source: ts
                format: '2006-01-02 15:04:05 -0700'

{% endif %}

  #==============================================================#
  #                      pgBackrest Logs                         #
  #==============================================================#
{% if pgbackrest_enabled is defined and pgbackrest_enabled|bool %}
  - job_name: pgbackrest
    static_configs:
      - targets:
          - localhost
        labels:
          src: pgbackrest
          job: pgsql
          cls: {{ pg_cluster }}
          ins: {{ pg_cluster }}-{{ pg_seq }}
          __path__: {{ pgbackrest_log_dir }}/*.log

    pipeline_stages:
      - match:
          selector: '{src="pgbackrest"}'
          stages:
            - multiline:
                firstline: '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} \w+ \[\d+\]'
                max_wait_time: 8s
                max_lines: 128
            - regex:
                expression: '^(?P<ts>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} \w+) \[(?P<pid>\d+)\] (?P<pid>\d+) (?P<level>\w+).*$'
            - labels:
                level:
            - timestamp:
                source: ts
                format: '2006-01-02 15:04:05 MST'
{% endif %}

  #==============================================================#
  #                      Pgbouncer Logs                          #
  #==============================================================#
{% if pgbouncer_enabled is defined and pgbouncer_enabled|bool %}
  - job_name: pgbouncer
    static_configs:
      - targets:
          - localhost
        labels:
          src: pgbouncer
          job: pgsql
          cls: {{ pg_cluster }}
          ins: {{ pg_cluster }}-{{ pg_seq }}
          __path__: {{ pgbouncer_log_dir }}/pgbouncer.log

    pipeline_stages:
      - match:
          selector: '{src="pgbouncer"}'
          stages:
            - multiline:
                firstline: '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} \w+ \[\d+\]'
                max_wait_time: 8s
                max_lines: 128
            - regex:
                expression: '^(?P<ts>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} \w+) \[(?P<pid>\d+)\] (?P<pid>\d+) (?P<level>\w+).*$'
            - labels:
                level:
            - timestamp:
                source: ts
                format: '2006-01-02 15:04:05 MST'
{% endif %}

{% endif %}


{% if redis_cluster is defined and redis_node is defined %}
  ################################################################
  #                         Redis Logs                           #
  ################################################################
  - job_name: redis
    static_configs:
      - targets:
          - localhost
        labels:
          src: redis
          job: redis
          cls: {{ redis_cluster }}
          ins: {{ redis_cluster }}-{{ redis_node }}
          __path__: /var/log/redis/*.log

{% endif %}
